Vector Field Visualization and Data Recovery

Vector Field Visualization and Data Recovery

  1. ggvfields
  2. Data Recovery
  3. Conclusion

ggvfields

  1. Introduction of Problem
  2. Current Solutions
  3. Proposed Solutions ggvfields

Before we define the problem

What is a vector field?

First, what is a vector?

A vector is a mathematical object that has both magnitude and direction.

In \(\mathbb{R}^2\), a vector is represented as an ordered pair of numbers \((x, y)\), where \(x\) and \(y\) are the components of the vector along the \(x\)-axis and \(y\)-axis.

Vectors are arrows pointing from one point to another in the plane.

Before we define the problem

What is a vector field?

A vector field in \(\mathbb{R}^2\) is a function that maps each point \((x, y)\) to a vector in the plane.
If \(\mathbf{V}\) is a vector field in \(\mathbb{R}^2\), then:

\(\mathbf{V}: \mathbb{R}^2 \rightarrow \mathbb{R}^2\)

where \(\mathbf{V}(x, y) = (u(x, y), v(x, y))\) assigns to each point \((x, y)\) a vector \((u(x, y), v(x, y))\).

Before we define the problem

There are many applications across various fields:

  1. Physics:
    • Representing force fields (gravitational, electric, magnetic)
    • Describing the velocity field of particles in a fluid flow
  2. Engineering:
    • Modeling airflow over wings and around vehicles
  3. Meteorology:
    • Mapping wind velocities or ocean currents

How do we visualize a vector field?

The Problem: R

How would we visualize this vector field in R?

\[\mathbf{f}(x,y) = (-y, x)\]

The Problem: R

How would we visualize this vector field in R?

\[\mathbf{f}(x,y) = (-y, x)\]

library(tidyverse)

x <- seq(-10, 10, by = 1)
y <- seq(-10, 10, by = 1)

grid <-
  expand_grid(x = x, y = y) |> 
  mutate(u = -y, v = x) |> 
  mutate(norm = sqrt(x^2 + y^2)) |> 
  mutate(u = u/max(norm), v = v/max(norm))

ggplot(grid, aes(x = x, y = y)) +
  geom_segment(
    aes(xend = x + u, yend = y + v), 
    arrow = arrow(length = unit(0.1, "cm"))
    ) +
  theme_minimal() 

The Problem: R

The Problem: R

  • This is a lot of syntax
  • This requires a large burden on the user
  • It takes a lot to customize the plot
  • It is not even that attractive

Current Solutions: Python

import numpy as np
import matplotlib.pyplot as plt

# Create a grid of points
x = np.linspace(-10, 10, 20)
y = np.linspace(-10, 10, 20)
X, Y = np.meshgrid(x, y)

# Define the vector field
U = -Y
V = X

# Plot the vector field
plt.quiver(X, Y, U, V)

Current Solutions: Python

Current Solutions: Mathematica

VectorPlot[{x, -y}, {x, -3, 3}, {y, -3, 3}]
# VectorPlot[{{x, -y}, {x^2, y^2}}, {x, -3, 3}, {y, -3, 3}]

Proposed Solutions: ggvfields

Requirements

  • Correct
  • Attractive
  • Simple
  • Familiar

Proposed Solutions: ggvfields

Install from Github

remotes::install_github("dusty-turner/ggvfields")

Load the package

library(ggvfields)

geom_vector_field()

Let’s explore the vector field defined by the function:

\[\mathbf{V}(x,y) = (-y, x)\]

f <- function(v) {
  x <- v[1]
  y <- v[2]
  c(-y, x)
}

A very simple and familiar implementation

ggplot() +
  geom_vector_field(fun = f, xlim = c(-10, 10), ylim = c(-10, 10)) 

geom_vector_field()

ggplot() +
  geom_vector_field(fun = f, xlim = c(-10, 10), ylim = c(-10, 10)) 

geom_vector_field()

By default, center and scale by the norm \(\mathbf{w} = (u, v)\) given by:

\[|\mathbf{w}| = \sqrt{u^2 + v^2}\]

ggplot() +
  geom_vector_field(fun = f, xlim = c(-10, 10), ylim = c(-10, 10), 
                    center = TRUE, normalize = TRUE
                    ) 

geom_vector_field()

If desired, we could also map the norm to a number of aesthetics. For example

Color:

ggplot() +
  geom_vector_field(
    aes(color = after_stat(norm)),
    xlim = c(-10, 10), ylim = c(-10, 10), 
    fun = f 
    ) 

Or alpha:

ggplot() +
  geom_vector_field(
    aes(alpha = after_stat(norm)),
    xlim = c(-10, 10), ylim = c(-10, 10), 
    fun = f 
    ) 

Calculus Concepts in Vector Fields

\(\mathbf{F} = \langle \mathbf{F}_x(x,y), \mathbf{F}_y(x,y) \rangle\)

Divergence

The divergence of a vector field \(\mathbf{F}\) in \(\mathbb{R}^2\) is defined by: \[\text{div} \, \mathbf{F} = \frac{\partial \mathbf{F}_x}{\partial x} + \frac{\partial \mathbf{F}_y}{\partial y}\] Indicates how much the vector field spreads out or converges at a point.

Curl

The curl of a vector field \(\mathbf{F}\) in \(\mathbb{R}^2\) is defined by: \[\text{curl} \, \mathbf{F} = \frac{\partial \mathbf{F}_y}{\partial x} - \frac{\partial \mathbf{F}_x}{\partial y}\] Measures the rotation or swirling strength at a point.

Laplace Operator

The Laplacian of the vector field \(\mathbf{F}\) is given by: \[\Delta \mathbf{F} = \frac{\partial^2 \mathbf{F}_x}{\partial x^2} + \frac{\partial^2 \mathbf{F}_x}{\partial y^2} + \frac{\partial^2 \mathbf{F}_y}{\partial x^2} + \frac{\partial^2 \mathbf{F}_y}{\partial y^2}\] Describes how the vector field spreads out or compresses at different points.

Directional Derivative

The directional derivative of a vector field measures the rate of change of the field in a specified direction. It is given by: \[D_{\mathbf{v}} \mathbf{F} = \frac{\partial \mathbf{F}_x}{\partial x} v_x + \frac{\partial \mathbf{F}_x}{\partial y} v_y + \frac{\partial \mathbf{F}_y}{\partial x} v_x + \frac{\partial \mathbf{F}_y}{\partial y} v_y\] Represents the rate of change of each component of the field in a given direction.

geom_vector_field()

ggplot() +
  geom_vector_field(
    aes(color = after_stat(divergence)),
    xlim = c(-10, 10), ylim = c(-10, 10), 
    fun = f 
    ) 

geom_vector_field()

ggplot() +
  geom_vector_field(
    aes(color = after_stat(curl)),
    xlim = c(-10, 10), ylim = c(-10, 10), 
    fun = f 
    ) 

geom_vector_field()

g <- function(v) {
  x <- v[1]
  y <- v[2]
  c(-sin(y), cos(x))
}

ggplot() +
  geom_vector_field(
    aes(color = after_stat(laplacian)),
    xlim = c(-10, 10), ylim = c(-10, 10), 
    fun = g 
    ) 

geom_vector_field()

Future Work

ggplot() +
  geom_vector_field(
    aes(color = after_stat(norm) 
        ),
    xlim = c(-10, 10), ylim = c(-10, 10), 
    fun = f 
    ) 

geom_vector_field()

Future Work

ggplot() +
  geom_vector_field(
    aes(color = after_stat(norm), 
        length = after_stat(norm)
        ),
    xlim = c(-10, 10), ylim = c(-10, 10), 
    fun = f 
    ) +
  scale_length_continuous(guide = "legend")
# scale_length_continuous(guide = "none")

geom_vector_field()

Future Work

geom_vector_field()

Future Work:

geom_vector_field()

Future Work:

Revisit the Problem: R

How else could we visualize this vector field in R?

\[\mathbf{f}(x,y) = (-y, x)\]

Revisit the Problem: R

Revisit the Problem: R

Revisit the Problem: R

Current Solutions: Mathematica

StreamPlot[{-1 - x^2 + y, 1 + x - y^2}, {x, -3, 3}, {y, -3, 3}]

Current Solutions: Python

import numpy as np
import matplotlib.pyplot as plt

Y, X = np.mgrid[-3:3:100j, -3:3:100j]

U = -1 - X**2 + Y
V = 1 + X - Y**2

plt.streamplot(X, Y, U, V)
plt.show()

Current Solutions: Python

geom_streamplot()

How to plot this in R?

\[\mathbf{f}(x,y) = (-1 - x^2 + y, 1 + x - y^2)\]

f <- function(v) {
  x <- v[1]
  y <- v[2]
  c(-1 - x^2 + y, 1 + x - y^2)
}
  1. Pick a starting point
  2. Trace the vector throughout the region
  3. Repeat until the region is sufficiently filled with streamlines

This sounds a lot like…

Euler’s method

geom_streamplot()

euler_integrate <- function(xi, yi, f, ds) {

  while (is_inside_plot) {
    uv <- f(c(xi, yi))
    u <- uv[1]
    v <- uv[2]
    dx <- ds * (u / norm)
    dy <- ds * (v / norm)
    xi <- xi + dx
    yi <- yi + dy
    
    xy_traj <- append(xy_traj, list(c(xi, yi)))
  }
}

Euler’s method steps:

  1. Start with the initial conditions \((x_0, y_0)\).

  2. Choose a step size \(h\).

  3. Compute for \(n = 0, 1, 2, \ldots\)

  • \(x_{n+1} = x_n + h \cdot f_1(x_n, y_n)\)

  • \(y_{n+1} = y_n + h \cdot f_2(x_n, y_n)\)

  1. Set termination condition

geom_streamplot()

geom_streamplot()

geom_streamplot()

geom_streamplot()

Considerations

  • Where do we draw these streams?

Spiral Traversal

geom_streamplot()

Considerations

  • Where do we draw these streams?
  • We don’t want to allow them to get too close

geom_streamplot()

Considerations

  • Where do we draw these streams?
  • We don’t want to allow them to get too close

geom_streamplot()

show

  • diamond
  • inset square
  • inset circle

geom_streamplot()

ggplot() +
  geom_streamplot(
    fun = f, xlim = c(-3, 3), ylim = c(-3, 3), 
    ) +
  coord_fixed() +
  theme_minimal()

geom_streamplot()

ggplot() +
  geom_streamplot(
    fun = f, xlim = c(-3, 3), ylim = c(-3, 3), 
    chop = TRUE
    ) +
  coord_fixed() +
  theme_minimal()

geom_streamplot()

ggplot() +
  geom_streamplot(
    fun = f, xlim = c(-3, 3), ylim = c(-3, 3), 
    chop = TRUE, scale_stream = 2, mask_shape_type = "diamond", n = 50
    ) +
  coord_fixed() +
  theme_minimal()

geom_streamplot()

Future work

geom_streamplot()

future work
- color by calculus measure

geom_complex_function

f <- function(z) (z^2 + 1) / (z^2 - 1)

ggplot() +
  geom_complex_function(fun = f, relim = c(-2, 2), imlim = c(-2, 2), n = 100) +
  labs(x = "Real", y = "Imaginary") +
  coord_fixed() +
  theme(legend.box = "horizontal")

geom_complex_function

geom_complex_function

  • future work

Data Recovery

  1. Introduction of Problem
  2. Current Solutions
  3. Proposed Solution

The Problem:

Imagine one of several scenarios
- Researcher who desires to replicate another’s research
- Researcher who wants to use an previous study’s results as a prior for their own

Current Solutions

By hand

  • slow
  • error prone
mtcars |> 
  ggplot(aes(hp, mpg)) +
  geom_point()

Current Solutions

  • email authors
  • many reasons why this could go wrong
  • such as unwilling/unable to share data

Current Solutions

plotdigitizer
automeris.io
engegue-digitizer
(show images of this)

  • Problems: require user interaction, technical expertise, not 100% accurate

ChatGPT

  • Problems: cost money, not 100% accurate, different answers every time asked

Proposed Solution

  1. Neural Network Solution

  2. Methodology

    • All Assumptions made in first model
    • Data Generation
    • AWS implementation (details)
  3. Challenges

    • Money
    • Time
    • Size of neural network
  4. Preliminary results with assumptions

  5. Preliminary results by removing assumptions

  6. Current unsolved issues

    • Unlimited y axis
    • Learn y axis?
  7. Where to go from here

Conclusion Slides